package com.hanxiaozhang.threadbase1ndedition.no10threadpool;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 〈一句话功能简述〉<br>
 * 〈固定大小线程池〉
 * <p>
 * 使用固定大小线程池寻找集合中的质数
 *
 * @author hanxinghua
 * @create 2021/11/25
 * @since 1.0.0
 */
public class No7FixedThreadPool {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // 一个线程去运行
        long start = System.currentTimeMillis();
        getPrime(1, 200000);
        long end = System.currentTimeMillis();
        System.out.println("一个线程去运行的时间: " + (end - start));

        // 多个线程去运行
        ExecutorService service = Executors.newFixedThreadPool(4);
        Task t1 = new Task(1, 80000);
        Task t2 = new Task(80001, 130000);
        Task t3 = new Task(130001, 170000);
        Task t4 = new Task(170001, 200000);

        Future<List<Integer>> f1 = service.submit(t1);
        Future<List<Integer>> f2 = service.submit(t2);
        Future<List<Integer>> f3 = service.submit(t3);
        Future<List<Integer>> f4 = service.submit(t4);

        start = System.currentTimeMillis();
        f1.get();
        f2.get();
        f3.get();
        f4.get();
        end = System.currentTimeMillis();

        System.out.println("多个线程去运行的时间: " + (end - start));
    }

    static class Task implements Callable<List<Integer>> {
        int startPos, endPos;

        Task(int s, int e) {
            this.startPos = s;
            this.endPos = e;
        }

        @Override
        public List<Integer> call() throws Exception {
            List<Integer> r = getPrime(startPos, endPos);
            return r;
        }

    }

    /**
     * 判断一个数是不是质数
     *
     * @param num
     * @return
     */
    static boolean isPrime(int num) {
        for (int i = 2; i <= num / 2; i++) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取质数
     *
     * @param start
     * @param end
     * @return
     */
    static List<Integer> getPrime(int start, int end) {
        List<Integer> results = new ArrayList<>();
        for (int i = start; i <= end; i++) {
            if (isPrime(i)) {
                results.add(i);
            }
        }

        return results;
    }
}
